class_name HealthComponent
extends BaseComponent

var cur_health:int = 0
var cur_health_state:GameEnum.HealthState = GameEnum.HealthState.Null
var cur_health_cache:float = 0
var cur_stamina:float = 0:
	get:
		return cur_stamina
	set(value):
		var cur_max_stamina = cur_entity.get_entity_data().max_stamina
		cur_stamina = value
		cur_stamina = clamp(cur_stamina,0,cur_max_stamina)
		stamina_changed.emit(cur_stamina,cur_max_stamina)
var stamina_is_consuming:bool = false
signal on_cur_health_changed(cur_health,cur_max_health)
signal on_cur_max_health_changed(cur_health,cur_max_health)
signal on_cur_health_state_changed(new_health_state)
signal on_hit(cur_health)
signal on_recover(cur_health)
signal stamina_changed(cur_stamina,cur_max_stamina)
	
func get_cur_health() -> int:
	return cur_health
func on_data_changed(change_tag:String):
	if change_tag == "max_health":
		var pre_cur_health = cur_health
		cur_health = min(cur_health,cur_entity.get_entity_data().max_health)
		on_cur_max_health_changed.emit(cur_health,cur_entity.get_entity_data().max_health)
		if cur_health != pre_cur_health:
			on_cur_health_changed.emit(cur_health,cur_entity.get_entity_data().max_health)
		check_health_state()
	elif change_tag == "max_stamina":
		stamina_changed.emit(cur_stamina,cur_entity.get_entity_data().max_stamina)
	
func hit(damage:TempEntityData):
	if damage.value <= 0:
		return
	cur_health_cache -= damage.value
	var val:int = cur_health_cache
	cur_health_cache -= val
	if val >= 0:
		return
	cur_health = clamp(cur_health + val,0,cur_entity.get_entity_data().max_health)
	on_cur_health_changed.emit(cur_health,cur_entity.get_entity_data().max_health)
	on_hit.emit(cur_health)
	
func recover(recovery:TempEntityData):
	if recovery.value <= 0:
		return
	cur_health_cache += recovery.value
	var val:int = cur_health_cache
	cur_health_cache -= val
	if val <= 0:
		return
	cur_health = clamp(cur_health + val,0,cur_entity.get_entity_data().max_health)
	on_cur_health_changed.emit(cur_health,cur_entity.get_entity_data().max_health)
	on_recover.emit(cur_health)
	
func check_health_state():
	var pre_cur_health_state = cur_health_state
	if cur_health == cur_entity.get_entity_data().max_health:
		cur_health_state = GameEnum.HealthState.Full
	elif cur_health > 0 and cur_health < cur_entity.get_entity_data().max_health:
		cur_health_state = GameEnum.HealthState.Hurt
	elif cur_health == 0:
		cur_health_state = GameEnum.HealthState.Death
	if cur_health_state != pre_cur_health_state:
		on_cur_health_state_changed.emit(cur_health_state)
func set_stamina_is_consuming(is_consuming:bool):
	stamina_is_consuming = is_consuming
func consume_stamina(stamina:float) -> bool:
	if cur_stamina >= stamina:
		cur_stamina -= stamina
		return true
	return false
func reply_stamina(delta:float):
	if not GameManager.get_cur_game_state() == GameEnum.GameState.Gaming or stamina_is_consuming:
		return
	var cur_max_stamina = cur_entity.get_entity_data().max_stamina
	if cur_stamina < cur_max_stamina:
		cur_stamina += cur_entity.get_entity_data().stamina_reply_per_second * delta
	
func destroy():
	if cur_health_state != GameEnum.HealthState.Death:
		return
	cur_health_state = GameEnum.HealthState.Dead
	on_cur_health_state_changed.emit(cur_health_state)
	owner.queue_free()
func init_component(entity):
	super.init_component(entity)
	cur_entity.get_entity_data().data_changed.connect(on_data_changed)
	cur_health = 0
	cur_health_state = GameEnum.HealthState.Null
	cur_health_cache = 0
	cur_health = cur_entity.get_entity_data().max_health
	cur_stamina = cur_entity.get_entity_data().max_stamina
	check_health_state()
	
func _init() -> void:
	component_name = "HealthComponent"
func _process(delta: float) -> void:
	reply_stamina(delta)
